package com.cyy.common.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyy.common.constant.Constants;
import com.cyy.common.domain.BaseEntity;
import com.cyy.common.exception.ProcessException;
import com.cyy.common.mapper.DictDataMapper;
import com.cyy.common.mapper.DictTypeMapper;
import com.cyy.common.pojo.dto.DictDataFormDto;
import com.cyy.common.pojo.dto.common.OptionDto;
import com.cyy.common.pojo.entity.DictData;
import com.cyy.common.pojo.entity.DictType;
import com.cyy.common.pojo.query.system.SystemDictDataQuery;
import com.cyy.common.pojo.vo.system.SystemDictDataVo;
import com.cyy.common.service.DictDataService;
import com.cyy.common.utils.PageUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 字典数据 服务实现类
 * </p>
 *
 * @author 曹云友
 * @since 2024-04-12
 */
@Service
@RequiredArgsConstructor
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper, DictData> implements DictDataService {

    private final DictTypeMapper dictTypeMapper;


    @Override
    public IPage<SystemDictDataVo> getPage(SystemDictDataQuery query) {
        return baseMapper.getPage(PageUtils.getPage(), query);
    }

    @Override
    public List<OptionDto<String, String>> getDictOptions(String typeCode) {

        // 查询
        DictType dictType = Optional.ofNullable(dictTypeMapper.selectOne((Wrappers.<DictType>lambdaQuery()
                        .select(BaseEntity::getId)
                        .eq(DictType::getDictType, typeCode))))
                .orElseThrow(() -> new ProcessException("未找到对应的字典类型信息"));


        List<DictData> dictDatas = baseMapper.selectList(Wrappers.<DictData>lambdaQuery().eq(DictData::getDictTypeId, dictType.getId()));

        if (CollectionUtil.isEmpty(dictDatas)) {
            return null;
        }

        return dictDatas.stream().map(item -> {
            OptionDto<String, String> optionDto = new OptionDto<>();
            optionDto.setLabel(item.getLabel());
            optionDto.setValue(item.getValue());
            return optionDto;
        }).toList();
    }

    @Override
    public DictDataFormDto getDictFormData(Integer id) {
        Assert.isFalse(Objects.isNull(id), "参数错误！");

        DictData dictData = baseMapper.selectOne(Wrappers.<DictData>lambdaQuery().eq(BaseEntity::getId, id));
        if (Objects.isNull(dictData)) {
            throw new ProcessException("未找到对应字典数据");
        }
        DictDataFormDto dto = new DictDataFormDto();
        BeanUtils.copyProperties(dictData, dto);

        return dto;
    }

    @Override
    public void addDict(DictDataFormDto dto) {

        Assert.isFalse(Objects.isNull(dto.getDictTypeId())
                        || StringUtils.isAnyBlank(dto.getLabel(), dto.getValue()),
                "参数错误");
        // 查询是否存在对应的类型，以及是否已存在对应的值
        boolean exists = dictTypeMapper.exists(Wrappers.<DictType>lambdaQuery().eq(BaseEntity::getId, dto.getDictTypeId()));
        if (!exists) {
            throw new ProcessException("未找到对应的字典类型");
        }
        boolean dataExists = baseMapper.exists(Wrappers.<DictData>lambdaQuery()
                .eq(DictData::getDictTypeId, dto.getDictTypeId())
                .eq(DictData::getValue, dto.getValue())
        );
        if (dataExists) {
            throw new ProcessException("因存在对应的字典数据，请勿重复添加");
        }
        // 参数判断
        DictData dictData = new DictData();
        BeanUtils.copyProperties(dto, dictData);
        dictData.setId(null);

        this.save(dictData);
    }

    @Override
    public void updateDict(DictDataFormDto dto) {
        Assert.isFalse(ObjectUtils.allNull(dto.getId(), dto.getDictTypeId()),
                "参数错误");
        // 查询是否存在对应的类型，以及是否已存在对应的值
        boolean exists = dictTypeMapper.exists(Wrappers.<DictType>lambdaQuery().eq(BaseEntity::getId, dto.getDictTypeId()));
        if (!exists) {
            throw new ProcessException("未找到对应的字典类型");
        }

        DictData dictData = new DictData();
        BeanUtils.copyProperties(dto, dictData);

        this.updateById(dictData);

    }

    @Override
    public void deleteDict(String ids) {
        Assert.isFalse(StringUtils.isBlank(ids), "参数错误");

        List<String> idList = Arrays.asList(ids.split(Constants.COMMA));

        baseMapper.update(Wrappers.<DictData>lambdaUpdate()
                        .set(BaseEntity::getStatus,Boolean.FALSE)
                .in(BaseEntity::getId, idList));
    }
}
